package com.itheima.health.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.aliyuncs.exceptions.ClientException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.health.Exception.MyException;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrderSettingDao;
import com.itheima.health.dao.OrderSettingListDao;
import com.itheima.health.entity.PageResult;
import com.itheima.health.entity.QueryPageBean;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;

import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.service.OrderSettingListService;
import com.itheima.health.utils.DateUtils;
import com.itheima.health.utils.SMSUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author：Super
 * @Date: 2020/12/6 11:21
 */
@Service(interfaceClass = OrderSettingListService.class)
public class OrderSettingListServiceImpl implements OrderSettingListService {


    @Autowired
    private OrderSettingListDao orderSettingListDao;

    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private OrderDao orderDao;




    /**
     * 预约列表的分页查询
     * @param queryPageBean
     * @return
     */
    @Override
    public PageResult<Map<String, Object>> findPage(QueryPageBean queryPageBean,String option) {
        //使用插件进行分页展示
        PageHelper.startPage(queryPageBean.getCurrentPage(),queryPageBean.getPageSize());

        //判断查询条件是否为null
        if (!StringUtils.isEmpty(queryPageBean.getQueryString())) {
            //赋值添加%方便模糊查询
            queryPageBean.setQueryString("%"+queryPageBean.getQueryString()+"%");
        }

        //调用dao方法查询返回结果是Page<>
        Page<Map<String, Object>> orderPage = orderSettingListDao.findByCondition(queryPageBean.getQueryString(),option);

        return new PageResult<Map<String, Object>>(orderPage.getTotal(),orderPage.getResult());

    }


    /**
     * 取消预约
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelById(Integer id) {

        //取消预约分两步：1.把数据库中预约改成取消。2.在预约设置中，减少一个已预约数
        //1.把数据库中预约改成取消。
        orderSettingListDao.cancelById(id);

        //2.在预约设置中，减少一个已预约数
        //获取预约时间
        Order order = orderSettingListDao.findById(id);

        Date orderDate = order.getOrderDate();

        orderSettingListDao.subtractOrder(orderDate);

        //获取电话，给取消成功的会员发送取消短信
        Map<String, String> detailMap = orderSettingListDao.findDetailById(id);

        String telephone = detailMap.get("telephone");

        try {
            SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE,telephone,"666666");
        } catch (ClientException e) {
            throw new MyException("已取消预约成功，但是取消短信发送失败，请电话告知会员取消成功。");
//            e.printStackTrace();
        }


    }


    /**
     * 已到诊
     * @param id
     */
    @Override
    public void arrive(Integer id) {

        orderSettingListDao.arriveById(id);

    }


    /**
     * 通过id查询详细的预约数据
     * @param id
     * @return
     */
    @Override
    public Map<String, String> findDetailById(Integer id) {
        return orderSettingListDao.findDetailById(id);
    }


    /**
     * 查询已选套餐
     * @param id
     * @return
     */
    @Override
    public List<Integer> findsetmealIdsByOrderId(Integer id) {
        return orderSettingListDao.findsetmealIdsByOrderId(id);
    }


    /**
     * 修改预约数据
     * @param paramMap
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Map<String, String> paramMap) {


        //- 通过日期查询预约设置表
        String orderDateString = paramMap.get("orderDate");
        Date orderDate = null;
        try {
            // 日期应该在controller做验证后才进来的service
            orderDate = DateUtils.parseString2Date(orderDateString);
        } catch (Exception e) {
            throw new MyException("预约日期格式不正确");
        }
        OrderSetting orderSetting = orderSettingDao.findByOrderDate(orderDate);
        if(null == orderSetting) {
            //  - 没记录，报错，所选日期不能预约，请选择其它日期
            throw new MyException("所选日期不能预约，请选择其它日期");
        }
        //  - 有记录，判断是否约满
        if(orderSetting.getReservations() >= orderSetting.getNumber()) {
            //    - reservations>=number, 报错，所选日期预约已满，请选择其它日期
            throw new MyException("所选日期预约已满，请选择其它日期");
        }

        //获取数据库中没有修改过的数据oldOrder
        Integer orderId = Integer.valueOf(paramMap.get("id"));
        Order oldOrder = orderSettingListDao.findById(orderId);

        //创造更改的 新预约对象newOrder
        Order newOrder = new Order();
        newOrder.setMemberId(oldOrder.getMemberId());
        newOrder.setSetmealId(Integer.valueOf(paramMap.get("setmealIds")));
        newOrder.setOrderDate(orderDate);

        //通过预约日期，会员id,套餐id查询t_order
        List<Order> orderList = orderDao.findByCondition(newOrder);
        //    - 存在，则报错，已经预约过，请忽重复预约
        if(null != orderList && orderList.size() > 0){
            throw new MyException("已经预约过了，请忽重复预约");
        }

        //  - 更新已预约人数
        int count = orderSettingDao.editReservationsByOrderDate(orderSetting);
        //  - 并发，加分布式锁（利用数据库的行锁） where reservations>number
        //  - 如果更新失败，则返回0，报错，预约已满，请选择其它日期
        if(count == 0){
            throw new MyException("预约已满，请选择其它日期");
        }

        //对数据进行修改
        newOrder.setId(orderId);
        orderSettingListDao.update(newOrder);
        orderSettingListDao.subtractOrder(oldOrder.getOrderDate());

    }
}
